﻿#region Using directives

using System;
using System.Collections.Generic;
using System.Text;

using Microsoft.VisualStudio.TestTools.UnitTesting;

using Weazel.Math;

#endregion

namespace Weazel.Math.Test
{
  [TestClass]
  public class TestLogicalOperators
  {
    /**************************************************************************
		 * Negation (~ operator)
		 **************************************************************************/
    [TestMethod]
    public void TestNEG_1()
    {
      Integer a = new Integer(8, "0b00000000", false);
      Assert.AreEqual("11111111", (~a).ToBinaryString());
    }

    [TestMethod]
    public void TestNEG_2()
    {
      Integer a = new Integer(8, "0b11110000", false);
      Assert.AreEqual("00001111", (~a).ToBinaryString());
    }

    [TestMethod]
    public void TestNEG_3()
    {
      Integer a = new Integer(32, "0xFFFFFFFF", false);
      Assert.AreEqual("0", (~a).ToHexadecimalString());
    }

    [TestMethod]
    public void TestNegate_SingleBit()
    {
      Integer a = new Integer(1, "1", false);
      Assert.AreEqual("0", (~a).ToDecimalString());
    }

    /**************************************************************************
		 * Xor (^ operator)
		 **************************************************************************/
    [TestMethod]
    public void TestXOR_1()
    {
      Integer a = new Integer(8, "0b00000000", false);
      Integer b = new Integer(8, "0b11111111", false);
      Integer r = new Integer(8, false);

      Assert.AreEqual("11111111", (a ^ b).ToBinaryString());

      Integer.Xor(ref r, a, b);
      Assert.AreEqual("11111111", r.ToBinaryString());
    }

    [TestMethod]
    public void TestXOR_2()
    {
      Integer a = new Integer(8, "0b11110000", false);
      Integer b = new Integer(8, "0b11111111", false);
      Integer r = new Integer(8, false);

      Assert.AreEqual("00001111", (a ^ b).ToBinaryString());

      Integer.Xor(ref r, a, b);
      Assert.AreEqual("00001111", r.ToBinaryString());
    }

    [TestMethod]
    public void TestXOR_3()
    {
      Integer a = new Integer(32, "0xFFFFFFFF", false);
      Integer b = new Integer(8, "0xFF", false);
      Integer r = new Integer(32, false);

      Assert.AreEqual("ffffff00", (a ^ b).ToHexadecimalString());

      Integer.Xor(ref r, a, b);
      Assert.AreEqual("ffffff00", r.ToHexadecimalString());
    }

    [TestMethod]
    public void TestXOR_4()
    {
      Integer b = new Integer(64, "0xFFFFFFFFFFFFFFFF", false);
      Integer a = new Integer(8, "0xFF", false);
      Integer r = new Integer(64, false);

      Assert.AreEqual("ffffffffffffff00", (a ^ b).ToHexadecimalString());

      Integer.Xor(ref r, a, b);
      Assert.AreEqual("ffffffffffffff00", r.ToHexadecimalString());
    }

		[TestMethod]
		public void TestXOR_5()
		{
			Integer b = new Integer(64, "0x0F0F0F0F0F0F0F0F", false);
			Integer a = new Integer(64, "0xFFFFFFFFFFFFFFFF", false);
			Integer r = new Integer(32, false);

			Assert.AreEqual("f0f0f0f0f0f0f0f0", (a ^ b).ToHexadecimalString());

			Integer.Xor(ref r, a, b);
			Assert.AreEqual("f0f0f0f0", r.ToHexadecimalString());
		}

    [TestMethod]
    public void TestXor_SingleBit1()
    {
      Integer a = new Integer(1, "0", false);
      Integer b = new Integer(1, "1", false);
      Integer r = new Integer(1, false);

      Assert.AreEqual("1", (a ^ b).ToHexadecimalString());

      Integer.Xor(ref r, a, b);
      Assert.AreEqual("1", r.ToHexadecimalString());
    }

    [TestMethod]
    public void TestXor_SingleBit2()
    {
      Integer a = new Integer(1, "1", false);
      Integer b = new Integer(1, "1", false);
      Integer r = new Integer(1, false);

      Assert.AreEqual("0", (a ^ b).ToHexadecimalString());

      Integer.Xor(ref r, a, b);
      Assert.AreEqual("0", r.ToHexadecimalString());
    }

    [TestMethod]
    public void TestXor_SingleBit3()
    {
      Integer a = new Integer(1, "0", false);
      Integer b = new Integer(1, "0", false);
      Integer r = new Integer(1, false);

      Assert.AreEqual("0", (a ^ b).ToHexadecimalString());

      Integer.Xor(ref r, a, b);
      Assert.AreEqual("0", r.ToHexadecimalString());
    }

    /**************************************************************************
		 * And (& operator)
		 **************************************************************************/
    [TestMethod]
    public void TestAND_1()
    {
      Integer a = new Integer(8, "0b00000000", false);
      Integer b = new Integer(8, "0b11111111", false);
      Integer r = new Integer(8, false);

      Assert.AreEqual("00000000", (a & b).ToBinaryString());

      Integer.And(ref r, a, b);
      Assert.AreEqual("00000000", r.ToBinaryString());
    }

    [TestMethod]
    public void TestAND_2()
    {
      Integer a = new Integer(8, "0b11110000", false);
      Integer b = new Integer(8, "0b11111111", false);
      Integer r = new Integer(8, false);

      Assert.AreEqual("11110000", (a & b).ToBinaryString());

      Integer.And(ref r, a, b);
      Assert.AreEqual("11110000", r.ToBinaryString());
    }

    [TestMethod]
    public void TestAND_3()
    {
      Integer a = new Integer(64, "0xFFFFFFFFFFFFFFFF", false);
      Integer b = new Integer(8, "0xFF", false);
      Integer r = new Integer(64, false);

      Assert.AreEqual("ff", (a & b).ToHexadecimalString());

      Integer.And(ref r, a, b);
      Assert.AreEqual("ff", r.ToHexadecimalString());
    }

    [TestMethod]
    public void TestAND_4()
    {
      Integer b = new Integer(32, "0xFFFFFFFF", false);
      Integer a = new Integer(8, "0xFF", false);
      Integer r = new Integer(32, false);

      Assert.AreEqual("ff", (a & b).ToHexadecimalString());

      Integer.And(ref r, a, b);
      Assert.AreEqual("ff", r.ToHexadecimalString());
    }

		[TestMethod]
		public void TestAND_5()
		{
			Integer b = new Integer(64, "0x0101010101010101", false);
			Integer a = new Integer(64, "0x0101010101010101", false);
			Integer r = new Integer(32, false);

			Assert.AreEqual("101010101010101", (a & b).ToHexadecimalString());

			Integer.And(ref r, a, b);
			Assert.AreEqual("1010101", r.ToHexadecimalString());
		}

    [TestMethod]
    public void TestAnd_SingleBit1()
    {
      Integer b = new Integer(1, "1", false);
      Integer a = new Integer(1, "0", false);
      Integer r = new Integer(1, false);

      Assert.AreEqual("0", (a & b).ToHexadecimalString());

      Integer.And(ref r, a, b);
      Assert.AreEqual("0", r.ToHexadecimalString());
    }

    [TestMethod]
    public void TestAnd_SingleBit2()
    {
      Integer b = new Integer(1, "1", false);
      Integer a = new Integer(1, "1", false);
      Integer r = new Integer(1, false);

      Assert.AreEqual("1", (a & b).ToHexadecimalString());

      Integer.And(ref r, a, b);
      Assert.AreEqual("1", r.ToHexadecimalString());
    }

    [TestMethod]
    public void TestAnd_SingleBit3()
    {
      Integer b = new Integer(1, "0", false);
      Integer a = new Integer(1, "0", false);
      Integer r = new Integer(1, false);

      Assert.AreEqual("0", (a & b).ToHexadecimalString());

      Integer.And(ref r, a, b);
      Assert.AreEqual("0", r.ToHexadecimalString());
    }

    /**************************************************************************
		 * Or (| operator)
		 **************************************************************************/
    [TestMethod]
    public void TestOR_1()
    {
      Integer a = new Integer(8, "0b00000000", false);
      Integer b = new Integer(8, "0b11111111", false);
      Integer r = new Integer(8, false);

      Assert.AreEqual("11111111", (a | b).ToBinaryString());

      Integer.Or(ref r, a, b);
      Assert.AreEqual("11111111", r.ToBinaryString());
    }

    [TestMethod]
    public void TestOR_2()
    {
      Integer a = new Integer(8, "0b11110000", false);
      Integer b = new Integer(8, "0b11111111", false);
      Integer r = new Integer(8, false);

      Assert.AreEqual("11111111", (a | b).ToBinaryString());

      Integer.Or(ref r, a, b);
      Assert.AreEqual("11111111", r.ToBinaryString());
    }

    [TestMethod]
    public void TestOR_3()
    {
      Integer a = new Integer(32, "0xFFFFFF00", false);
      Integer b = new Integer(8, "0xF0", false);
      Integer r = new Integer(32, false);

      Assert.AreEqual("fffffff0", (a | b).ToHexadecimalString());

      Integer.Or(ref r, a, b);
      Assert.AreEqual("fffffff0", r.ToHexadecimalString());
    }

    [TestMethod]
    public void TestOR_4()
    {
      Integer b = new Integer(64, "0xFFFFFFFFFFFFFF00", false);
      Integer a = new Integer(8, "0xF0", false);
      Integer r = new Integer(64, false);

      Assert.AreEqual("fffffffffffffff0", (a | b).ToHexadecimalString());
      Assert.AreEqual("fffffffffffffff0", (b | a).ToHexadecimalString());

      Integer.Or(ref r, a, b);
      Assert.AreEqual("fffffffffffffff0", r.ToHexadecimalString());
    }

		[TestMethod]
		public void TestOR_5()
		{
			Integer b = new Integer(64, "0xf0f0f0f0f0f0f0f0", false);
			Integer a = new Integer(64, "0x0f0f0f0f0f0f0f0f", false);
			Integer r = new Integer(32, false);

			Assert.AreEqual("ffffffffffffffff", (a | b).ToHexadecimalString());
			Assert.AreEqual("ffffffffffffffff", (b | a).ToHexadecimalString());

			Integer.Or(ref r, a, b);
			Assert.AreEqual("ffffffff", r.ToHexadecimalString());
		}

    [TestMethod]
    public void TestOr_SingleBit1()
    {
      Integer b = new Integer(1, "1", false);
      Integer a = new Integer(1, "1", false);
      Integer r = new Integer(1, false);

      Assert.AreEqual("1", (a | b).ToHexadecimalString());
      Assert.AreEqual("1", (b | a).ToHexadecimalString());

      Integer.Or(ref r, a, b);
      Assert.AreEqual("1", r.ToHexadecimalString());
    }

    [TestMethod]
    public void TestOr_SingleBit2()
    {
      Integer b = new Integer(1, "0", false);
      Integer a = new Integer(1, "1", false);
      Integer r = new Integer(1, false);

      Assert.AreEqual("1", (a | b).ToHexadecimalString());
      Assert.AreEqual("1", (b | a).ToHexadecimalString());

      Integer.Or(ref r, a, b);
      Assert.AreEqual("1", r.ToHexadecimalString());
    }

    [TestMethod]
    public void TestOr_SingleBit3()
    {
      Integer b = new Integer(1, "0", false);
      Integer a = new Integer(1, "0", false);
      Integer r = new Integer(1, false);

      Assert.AreEqual("0", (a | b).ToHexadecimalString());
      Assert.AreEqual("0", (b | a).ToHexadecimalString());

      Integer.Or(ref r, a, b);
      Assert.AreEqual("0", r.ToHexadecimalString());
    }
  }
}
